package com.wiselink.naver.productcatalog.request;

import com.wiselink.naver.productcatalog.request.enums.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.List;

/**
 * 原始产品信息结构
 * 该结构是表达产品信息中与原始产品属性相对应的产品数据的结构。
 * <p>
 * 此结构用于 API 调用的请求/响应。
 * 该结构的一个对象代表一种产品的原始产品信息。
 * 每个产品单元的原始产品信息仅包含在单个结构中，但作为分层结构中的姊妹实体，它可以与智能商店渠道产品结构或购物橱渠道产品结构一起使用。
 * 下面的 API 中使用了该结构。
 * 产品注册、渠道产品查询、渠道产品修改、原产品查询、原产品修改等
 */
@Getter
@Setter
@ToString(callSuper = true)
public class OriginProduct {
    /**
     * 商品销售状态代码
     * 要变更的商品销售状态
     * 상품 판매 상태 코드
     * 변경하려는 상품 판매 상태
     */
    @NotNull(message = "商品销售状态代码不能为空")
    private StatusType statusType;
    /**
     * 商品销售类型代码
     * 商品原料药中用来表示商品销售种类的代码。 未输入时作为NEW（新商品）保存。
     * 상품 판매 유형 코드
     * 상품 API에서 상품의 판매 유형을 나타내기 위해 사용하는 코드입니다. 미입력 시 NEW(새 상품)로 저장됩니다.
     */
    private SaleType saleType;
    /**
     * Leaf类别ID 取值来自目录查询API
     * 注册商品时必需具备。 修改商品时，输入目录ID（modelId）时，是必须的。 要求修改标准型期权类别商品的，CategoryId变更请求不予受理（租赁商品已正常处理）。
     * 리프 카테고리 ID
     * 상품 등록 시 필수입니다. 상품 수정 시 카탈로그 ID(modelId)를 입력한 경우 필수입니다. 표준형 옵션 카테고리 상품 수정 요청의 경우 CategoryId 변경 요청은 무시됩니다(렌탈 상품은 정상 처리됨).
     */
    private String leafCategoryId;
    /**
     * 商品名
     * 상품명
     */
    @NotNull(message = "商品名不能为空")
    private String name;
    /**
     * 商品详情
     * 상품 상세 정보
     */
    @NotNull(message = "商品详情不能为空")
    private String detailContent;
    /**
     * 商品形象
     * <p>可提供具有代表性的图像（推荐1000x1000像素）作为商品图像，以及最多9个附加图像列表。 代表性图像是必需的，附加图像是可选的。 图像URL必须上传图像到商品图像多件注册API，并输入返回的URL值。</p>
     * 상품 이미지
     * 상품 이미지로 대표 이미지(1000x1000픽셀 권장)와 최대 9개의 추가 이미지 목록을 제공할 수 있습니다. 대표 이미지는 필수이고 추가 이미지는 선택 사항입니다. 이미지 URL은 반드시 상품 이미지 다건 등록 API로 이미지를 업로드하고 반환받은 URL 값을 입력해야 합니다.
     */
    @NotNull(message = "商品形象不能为空")
    private Images images;
    /**
     * 开始销售日期
     * <p>以"yyy-MM-dd'T'HH:mm[:ss][.SSS]XXX"格式输入。</p>
     * <date-time> (판매 시작 일시)
     * 'yyyy-MM-dd'T'HH:mm[:ss][.SSS]XXX' 형식으로 입력합니다.
     */
    private String saleStartDate;
    /**
     * 销售结束日期
     * <p>以"yyy-MM-dd'T'HH:mm[:ss][.SSS]XXX"格式输入。</p>
     * <date-time> (판매 종료 일시)
     * 'yyyy-MM-dd'T'HH:mm[:ss][.SSS]XXX' 형식으로 입력합니다.
     */
    private String saleEndDate;
    /**
     * 售价
     * <int64> (상품 판매 가격) <= 999999990
     */
    @NotNull(message = "售价不能为空")
    @Min(value = 0, message = "售价不能小于0")
    @Max(value = 999999990, message = "售价不能超过999999990")
    private Long salePrice;
    /**
     * 库存数量
     * <int32> (재고 수량) <= 99999999
     */
    @Min(value = 0, message = "库存数量不能小于0")
    @Max(value = 99999999, message = "库存数量不能超过99999999")
    private Integer stockQuantity;
    /**
     * 配送信息
     * <p>可以设置配送方式及配送费等。 如果不输入，将登记为没有配送的商品。 对于租用或买菜的商品，必须填写交货信息。</p>
     * 배송 정보
     * 배송 방식 및 배송비 등을 설정할 수 있습니다. 입력하지 않으면 배송 없는 상품으로 등록됩니다. 렌탈 또는 장보기 상품의 경우에는 배송 정보를 필수로 입력해야 합니다.
     */
    private DeliveryInfo deliveryInfo;

    /**
     * 物流公司信息
     * <p>已设置Naver Fullfillment的商品会被查询。</p>
     * 물류사 정보
     * 네이버 풀필먼트가 설정된 상품의 경우 조회됩니다.
     */
    private List<ProductLogistics> productLogistics;
    /**
     * 查询用原商品详细属性
     * 조회용 원상품 상세 속성
     */
    @NotNull(message = "商品详情不能为空")
    private DetailAttribute detailAttribute;
    /**
     * 商品顾客优惠信息
     * 상품 고객 혜택 정보
     */
    private CustomerBenefit customerBenefit;

    /**
     * 商品形象
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class Images {
        /**
         * 物体（图像）
         * 이미지
         */
        @NotNull(message = "物体（图像）不能为空")
        private RepresentativeImage representativeImage;
        /**
         * 附加图像
         * <p>添加图像列表。 最多9个.图片URL必须上传图片到商品图片多件注册API，并输入返回的URL值。</p>
         * 추가 이미지
         * 추가 이미지 목록. 최대 9개. 이미지 URL은 반드시 상품 이미지 다건 등록 API로 이미지를 업로드하고 반환받은 URL 값을 입력해야 합니다.
         */
        private List<OptionalImage> optionalImages;
    }

    /**
     * 物体图像
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class RepresentativeImage {
        /**
         * 图像 URL
         * 이미지 URL
         */
        @NotEmpty(message = "图像 URL不能为空")
        private String url;
    }

    /**
     * 附加图像
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class OptionalImage {
        /**
         * 图像 URL
         * 이미지 URL
         */
        @NotEmpty(message = "图像 URL不能为空")
        private String url;
    }

    /**
     * 配送信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class DeliveryInfo {
        /**
         * 配送方法类型代码
         * <p>Naver Fulfillment商品、配送属性SELLER_GUARANTEE（卖家到货保障）、配送属性HOPE_SELLER_GUARANTEE（卖家希望日期到货保障）时，配送方法只允许DELIVERY（快递、包裹、登记）。</p>
         * 배송 방법 유형 코드
         * 네이버 풀필먼트 상품, 배송 속성 SELLER_GUARANTEE(판매자 도착보장), 배송 속성 HOPE_SELLER_GUARANTEE(판매자 희망일 도착보장)인 경우 배송 방법은 DELIVERY(택배, 소포, 등기)만 허용됩니다.
         */
        @NotNull(message = "配送信息不能为空")
        private DeliveryType deliveryType;
        /**
         * 配送属性类型代码
         * <p>NAVER商品API中为了表示配送属性类型而使用的代码。 Naver Fulfillment商品不能设定OPTION_TODAY(各选项今天出发)</p>
         * 배송 속성 타입 코드
         */
        @NotNull(message = "配送属性类型代码不能为空")
        private DeliveryAttributeType deliveryAttributeType;
        /**
         * 快递公司 取值来自查询naver平台物流公司列表API
         * <p>DELIVERY（快递、包裹、挂号）时必需输入</p>
         * <p>参考订单>订货/发运处理>发运处理API的快递公司代码(delivery Company Code)，输入代码值。</p>
         * <p>配送属性为SELLER_GUARANTEE（卖方保证到货）、HOPE_SELLER_GUARANTEE（卖方保证到货日期）时，卖方信息>卖方物流>物流公司联动信息查询API中对应的deliveryTypes（配送属性）的logisticsCompanyId（物流公司ID）输入商品API的deliveryCompany（快递公司）。</p>
         * 택배사
         * DELIVERY(택배, 소포, 등기)일 때 필수 입력
         * 주문 > 발주/발송 처리 > 발송 처리 API의 택배사 코드(deliveryCompanyCode)를 참고하여 코드값을 입력합니다.
         * 배송 속성이 SELLER_GUARANTEE(판매자 도착보장), HOPE_SELLER_GUARANTEE(판매자 희망일 도착보장)인 경우 판매자정보 > 판매자 물류 > 물류사 연동 정보 조회 API에서 해당하는 deliveryTypes(배송 속성)의 logisticsCompanyId(물류사 ID)를 상품 API의 deliveryCompany(택배사)에 입력합니다.
         */
        private String deliveryCompany;
        /**
         * 卖方仓库ID
         * <p>配送属性为SELLER_GURANTEE（卖家到货保障）、HOPE_SELLER_GUARANTEE（卖家希望日期到货保障）时必需。此外，在配送属性中输入的卖家仓库ID值将被忽略。 销售者信息>销售者物流>销售者仓库信息查询API中填写相应的配送类型（配送属性）的仓库ID。</p>
         * 판매자 창고 ID
         * 배송 속성이 SELLER_GURANTEE(판매자 도착보장), HOPE_SELLER_GUARANTEE(판매자 희망일 도착보장)인 경우 필수. 그 밖의 배송 속성에 입력된 판매자 창고 ID값은 무시됩니다. 판매자정보 > 판매자물류 > 판매자 창고 정보 조회 API에서 해당하는 deliveryType(배송 속성)의 창고 ID를 입력합니다.
         */
        private String outboundLocationId;
        /**
         * 是否可以合并发货
         * <p>捆绑发货群代码已存在时，将自动设置为true。 如果发货属性为HOPE_SELLER_GUARANTEE（保证卖方希望的日期到达），则无法设置捆绑发货。</p>
         * 묶음배송 가능 여부
         * 묶음배송 그룹 코드가 존재하는 경우 자동으로 true로 설정됩니다. 배송 속성이 HOPE_SELLER_GUARANTEE(판매자 희망일 도착보장)인 경우 묶음배송을 설정할 수 없습니다.
         */
        private Boolean deliveryBundleGroupUsable;
        /**
         * 捆绑配送群组代码 取值来自获取naver店铺的仓库列表API
         * <p>如果合并发货为 true，合并发货组代码为空，则保存为默认组（如果发货属性为 ARRIVAL_GUARANTEE 除外）。</p>
         * 묶음배송 그룹 코드
         * 묶음배송 가능이 true이고 묶음배송 그룹 코드가 null이면 기본 그룹으로 저장됩니다.(배송 속성이 ARRIVAL_GUARANTEE인 경우 제외)
         */
        private Long deliveryBundleGroupId;
        /**
         * 快递配送地区代码
         * <p>快递配送地区代码。 Naver Fulfillment商品、卖家希望日期到货保障商品不能设置快递服务。</p>
         * 퀵서비스 배송 지역 코드
         * 퀵서비스 배송 지역 코드입니다. 네이버 풀필먼트 상품, 판매자 희망일 도착보장 상품은 퀵서비스를 설정할 수 없습니다.
         */
        private List<QuickServiceArea> quickServiceAreas;
        /**
         * 访问接收地址簿 ID 取值来自获取地址簿列表API
         * <p>上门取件地址代码。 Naver Fulfillment商品、卖家希望日期到货保障商品不能设定访问领取。</p>
         * 방문 수령 주소록 ID
         * 방문 수령 주소 코드. 네이버 풀필먼트 상품, 판매자 희망일 도착보장 상품은 방문 수령을 설정할 수 없습니다.
         */
        private Long visitAddressId;
        /**
         * 配送费信息
         * 배송비 정보
         */
        @NotNull(message = "配送费信息不能为空")
        private DeliveryFee deliveryFee;
        /**
         * 索赔（退货/换货）信息
         * 클레임(반품/교환) 정보
         */
        @NotNull(message = "索赔（退货/换货）信息不能为空")
        private ClaimDeliveryInfo claimDeliveryInfo;
        /**
         * 安装与否
         * <p>配送属性为HOPE_SELLER_GUARANTEE（保证卖家希望日期到达）时必需使用。 未输入时设定为false。 此外，如果输入到配送属性，则将被忽略。</p>
         * 설치 여부
         * 배송 속성이 HOPE_SELLER_GUARANTEE(판매자 희망일 도착보장)인 경우에만 필수. 미입력 시 false로 설정됩니다. 그 외 배송 속성에 입력한 경우 무시됩니다.
         */
        private Boolean installation;
        /**
         * 有无额外安装费
         * <p>如果安装与否为false，则无论输入的值如何，单独安装费用都设定为false。</p>
         * 별도 설치비 유무
         * 설치 여부가 false이면 별도 설치비 유무는 입력한 값에 관계 없이 false로 설정됩니다.
         */
        private Boolean installationFee;
        /**
         * 订制商品预定发送日期类型代码
         * <p>ETC只能用于修改货物，如果存在已保存的"订单后预期发货期"值或"直接录入型"则可以设置。</p>
         * 주문 제작 상품 발송 예정일 타입 코드
         * ETC는 상품 수정에만 사용 가능하며, 이미 저장된 '주문 후 예상 발송 기간' 값이 존재하거나 '직접 입력형'인 경우 설정 가능합니다.
         */
        private ExpectedDeliveryPeriodType expectedDeliveryPeriodType;
        /**
         * 预定日期直接输入值
         * 발송 예정일 직접 입력 값
         */
        private String expectedDeliveryPeriodDirectInput;
        /**
         * 今天出发的商品库存数量
         * 오늘출발 상품 재고 수량
         */
        private Integer todayStockQuantity;
        /**
         * 确认订单后是否制作商品
         * 주문 확인 후 제작 상품 여부
         */
        private Boolean customProductAfterOrderYn;
        /**
         * 希望日配送组编号
         * <p>配送属性类型代码为希望日配送，如果希望日配送组编号为Null，则保存为默认组。</p>
         * 희망일배송 그룹 번호
         * 배송 속성 타입 코드가 희망일배송이고 희망일배송 그룹 번호가 Null이면 기본 그룹으로 저장됩니다.
         */
        private Long hopeDeliveryGroupId;
        /**
         * 营业者通关销售与否
         * <p>只适用于出库地址在海外。 未输入时输入false。</p>
         * 사업자 통관 판매 여부
         * 출고지 주소가 해외인 경우에만 적용됩니다. 미입력 시 false로 입력됩니다.
         */
        private Boolean businessCustomsClearanceSaleYn;
    }

    /**
     * 配送费信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class DeliveryFee {
        /**
         * 配送费类型
         * <p>如果不输入运费类型，则设置为FREE（免费）。</p>
         * 배송비 타입
         * 배송비 타입을 입력하지 않으면 FREE(무료)로 설정됩니다.
         */
        private DeliveryFeeType deliveryFeeType;
        /**
         * 基本配送费
         * 기본 배송비
         */
        @Min(value = 0, message = "基本配送费不能小于0")
        @Max(value = 100000, message = "基本配送费不能超过100000")
        private Integer baseFee;
        /**
         * 免费条件金额
         * <p>运费类型为"有条件的免收"时填写。</p>
         * 무료 조건 금액
         * 배송비 유형이 '조건부 무료'일 경우 입력합니다.
         */
        @Min(value = 0, message = "免费条件金额不能小于0")
        @Max(value = 999999990, message = "免费条件金额不能超过999999990")
        private Integer freeConditionalAmount;
        /**
         * 基本配送费重复征收数量
         * <p>重复数量。运费类型为"按数量收费-重复区间"时填写。</p>
         * 기본 배송비 반복 부과 수량
         * 반복 수량. 배송비 유형이 '수량별 부과 - 반복 구간'일 경우 입력합니다.
         */
        private Integer repeatQuantity;
        /**
         * 配送费条件第2区间数量
         * <p>第2区间最小数量。 运费类型为"按数量计收-区间直接设置"时填写。</p>
         * 배송비 조건 2구간 수량
         * 2구간 최소 수량. 배송비 유형이 '수량별 부과 - 구간 직접 설정'일 경우 입력합니다.
         */
        private Integer secondBaseQuantity;
        /**
         * 配送费条件超过第2区间数量时追加配送费
         * <p>第2区间追加配送费。 运费类型为"按数量计收-区间直接设置"时填写。</p>
         * 배송비 조건 2구간 수량 초과 시 추가 배송비
         * 2구간 추가 배송비. 배송비 유형이 '수량별 부과 - 구간 직접 설정'일 경우 입력합니다.
         */
        private Integer secondExtraFee;
        /**
         * 配送费条件第3区间数量
         * <p>第3区间最小数量。 运费类型为"按数量计收-区间直接设置"时填写。</p>
         * 배송비 조건 3구간 수량
         * 3구간 최소 수량. 배송비 유형이 '수량별 부과 - 구간 직접 설정'일 경우 입력합니다.
         */
        private Integer thirdBaseQuantity;
        /**
         * 配送费条件超过第3区间时追加配送费
         * <p>第3区间追加配送费。 运费类型为"按数量计收-区间直接设置"时填写。</p>
         * 배송비 조건 3구간 초과 시 추가 배송비
         * 3구간 추가 배송비. 배송비 유형이 '수량별 부과 - 구간 직접 설정'일 경우 입력합니다.
         */
        private Integer thirdExtraFee;
        /**
         * 配送费结算方式代码
         * <p>NAVER商品API中为了表示配送费结算方式而使用的代码。</p>
         * 배송비 결제 방식 코드
         * 네이버 상품 API에서 배송비 결제 방식을 나타내기 위해 사용하는 코드입니다
         */
        private DeliveryFeePayType deliveryFeePayType;
        /**
         * 各地区追加配送费
         * 지역별 추가 배송비
         */
        private DeliveryFeeByArea deliveryFeeByArea;
        /**
         * 各地区差别配送费信息
         * 지역별 차등 배송비 정보
         */
        private String differentialFeeByArea;
    }

    /**
     * 索赔（退货/换货）信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class ClaimDeliveryInfo {
        /**
         * 未输入时设定为"基本退货快递公司（PRIMARY）"。
         * 退货快递公司优先类型
         * 반품 택배사 우선순위 타입
         * 미입력 시 '기본 반품 택배사(PRIMARY)'로 설정됩니다.
         */
        private ReturnDeliveryCompanyPriorityType returnDeliveryCompanyPriorityType;
        /**
         * 退货运费
         * 반품 배송비
         */
        @NotNull(message = "退货运费不能为空")
        @Min(value = 0, message = "退货运费不能小于0")
        @Max(value = 1000000, message = "退货运费不能超过1000000")
        private Integer returnDeliveryFee;
        /**
         * 交换运费
         * 교환 배송비
         */
        @NotNull(message = "交换运费不能为空")
        @Min(value = 0, message = "交换运费不能小于0")
        @Max(value = 1000000, message = "交换运费不能超过1000000")
        private Integer exchangeDeliveryFee;
        /**
         * 出库地地址簿编号 取值来自获取地址簿列表API
         * <p>如果运输属性为ARRIVAL_GUARANTEE（保证NAVER到达），则按空格键入。</p>
         * 출고지 주소록 번호
         * 배송 속성이 ARRIVAL_GUARANTEE(네이버 도착보장)인 경우 null로 입력합니다.
         */
        private Long shippingAddressId;
        /**
         * 退货/换货地址簿编号 取值来自获取地址簿列表API
         * 반품/교환지 주소록 번호
         */
        private Long returnAddressId;
        /**
         * 设置退货安心护理
         * 반품안심케어 설정
         */
        private Boolean freeReturnInsuranceYn;
    }

    /**
     * 物流公司信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class ProductLogistics {
        /**
         * 物流公司ID
         * <p>正在使用Naver Fulfillment服务时可输入，（卖家Fulfillment）物流公司联动信息查询API确认的物流公司ID。</p>
         * 물류사 ID
         * 네이버 풀필먼트 서비스를 이용 중인 경우 입력할 수 있으며, (판매자 풀필먼트)물류사 연동 정보 조회 API로 확인한 물류사 ID를 입력합니다.
         */
        @NotEmpty(message = "物流公司id不能为空")
        private String logisticsCompanyId;
        /**
         * 物流中心ID(强烈反对)
         * 물류센터 ID(deprecated)
         */
        private String logisticsCenterId;
    }

    /**
     * 查询用原商品详细属性
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class DetailAttribute {
        /**
         * NAVER购物搜索信息
         * 네이버 쇼핑 검색 정보
         */
        private NaverShoppingSearchInfo naverShoppingSearchInfo;
        /**
         * 品目编号
         * 품번
         */
        private String manufactureDefineNo;
        /**
         * 售后服务信息
         * A/S 정보
         */
        @NotNull(message = "售后服务信息不能为空")
        private AfterServiceInfo afterServiceInfo;
        /**
         * 购买数量设定信息
         * 구매 수량 설정 정보
         */
        private PurchaseQuantityInfo purchaseQuantityInfo;
        /**
         * 原产地信息
         * 원산지 정보
         */
        @NotNull(message = "原产地信息不能为空")
        private OriginAreaInfo originAreaInfo;
        /**
         * 卖方代码信息
         * 판매자 코드 정보
         */
        private SellerCodeInfo sellerCodeInfo;
        /**
         * 选项信息
         * <p>选项信息。您必须至少输入一个选项，即独立选项、组合选项和直接输入选项。 租赁商品只能使用组合型、直接输入型。</p>
         * <p>单独型选项和组合型选项不能一起使用。</p>
         * 옵션 정보
         * 옵션 정보. 단독형 옵션, 조합형 옵션, 직접 입력형 옵션 중 최소 한 개는 입력해야 합니다. 렌탈 상품의 경우 조합형, 직접 입력형만 사용 가능합니다.
         * <p>
         * 단독형 옵션과 조합형 옵션은 함께 사용할 수 없습니다.
         */
        private OptionInfo optionInfo;
        /**
         * 附加商品
         * <p>附加商品信息</p>
         * 추가 상품
         * 추가 상품 정보
         */
        private SupplementProductInfo supplementProductInfo;
        /**
         * 采购评估信息
         * <p>评论曝光设置信息</p>
         * 구매평 정보
         * 리뷰 노출 설정 정보
         */
        private PurchaseReviewInfo purchaseReviewInfo;
        /**
         * 关于 ISBN
         * ISBN 정보
         */
        private IsbnInfo isbnInfo;
        /**
         * 图书信息
         * <p>书目附加信息</p>
         * 도서 정보
         * 도서 항목 부가 정보
         */
        private BookInfo bookInfo;
        /**
         * 活动语句（替换宣传语句）
         * 이벤트 문구(홍보 문구 대체)
         */
        private String eventPhraseCont;
        /**
         * 生产日期
         * 제조일자 <date>
         */
        private String manufactureDate;
        /**
         * 上市日期
         * 출시일자 <date>
         */
        private String releaseDate;
        /**
         * 有效日期
         * 유효일자 <date>
         * 'yyyy-MM-dd' 형식 입력
         */
        private String validDate;
        /**
         * 增值税类型代码
         * 부가가치세 타입 코드
         */
        private TaxType taxType;
        /**
         * 认证信息列表
         * 인증 정보 목록
         */
        private List<ProductCertificationInfo> productCertificationInfos;
        /**
         * 是否排除认证对象的信息
         * 인증 대상 제외 여부 정보
         */
        private CertificationTargetExcludeContent certificationTargetExcludeContent;
        /**
         * 卖方特殊事项
         * 판매자 특이 사항
         */
        private String sellerCommentContent;
        /**
         * 是否使用卖家特殊事项
         * 판매자 특이 사항 사용 여부
         */
        private Boolean sellerCommentUsable;
        /**
         * 未成年人是否可以购买
         * 미성년자 구매 가능 여부
         */
        @NotNull(message = "未成年人是否可以购买不能为空")
        private Boolean minorPurchasable;
        /**
         * E优惠券
         * E쿠폰
         */
        private Ecoupon ecoupon;
        /**
         * 商品信息提供公告
         * 产品摘要信息
         * 商品登记时必需
         * 修改商品时，仅当输入原商品汇总信息时，方可省略。 在这种情况下，保留了已保存的商品汇总信息值。
         * 상품정보제공고시
         * 상품 요약 정보
         * 상품 등록 시 필수
         * 상품 수정 시에는 기존에 상품 요약 정보가 입력된 경우에만 생략할 수 있습니다. 이 경우 기존에 저장된 상품 요약 정보 값이 유지됩니다.
         */
        private ProductInfoProvidedNotice productInfoProvidedNotice;
        /**
         * 商品属性列表 取值来自根据categoryId搜索属性值列表API
         * 상품 속성 목록
         */
        private List<ProductAttribute> productAttributes;
        /**
         * 文化费所得抵扣与否
         * 문화비 소득공제 여부
         */
        private Boolean cultureCostIncomeDeductionYn;
        /**
         * 定制制作商品与否
         * 맞춤 제작 상품 여부
         */
        private Boolean customProductYn;
        /**
         * 是否自行制作商品
         * 자체 제작 상품 여부
         */
        private Boolean itselfProductionProductYn;
        /**
         * 是否认证与否
         * 브랜드 인증 여부
         */
        private Boolean brandCertificationYn;
        /**
         * SEO(Search engine optimization) 信息
         * SEO(Search engine optimization) 정보
         */
        private SeoInfo seoInfo;
        /**
         * 商品尺寸 尺寸信息
         * 상품 사이즈
         * 사이즈 정보
         */
        private ProductSize productSize;
    }

    /**
     * 商品顾客优惠信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class CustomerBenefit {
        /**
         * 卖方基本折扣政策
         * <p>设置为 mobileDiscount 模式的值被忽略。 以后可能会返还错误应答，请使用discount Method。</p>
         * 판매자 기본 할인 정책
         * mobileDiscountMethod로 설정한 값은 무시됩니다. 추후 오류 응답이 반환될 수 있으므로 discountMethod를 사용하세요.
         */
        private ImmediateDiscountPolicy immediateDiscountPolicy;
        /**
         * 商品购买积分政策
         * <p>卖家商品购买积分政策</p>
         * 상품 구매 포인트 정책
         * 판매자 상품 구매 포인트 정책
         */
        private PurchasePointPolicy purchasePointPolicy;
        /**
         * 购买评价积分政策
         * <p>卖家商品评价积分政策</p>
         * 구매평 포인트 정책
         * 판매자 상품 리뷰 포인트 정책
         */
        private ReviewPointPolicy reviewPointPolicy;
        /**
         * 无息分期付款政策
         * 무이자 할부 정책
         */
        private FreeInterestPolicy freeInterestPolicy;
        /**
         * 赠品政策
         * 사은품 정책
         */
        private GiftPolicy giftPolicy;
        /**
         * 复购折扣政策
         * <p>卖家复购折扣政策</p>
         * 복수 구매 할인 정책
         * 판매자 복수 구매 할인 정책
         */
        private MultiPurchaseDiscountPolicy multiPurchaseDiscountPolicy;
        /**
         * 预约折扣政策
         * 예약 할인 정책
         */
        private ReservedDiscountPolicy reservedDiscountPolicy;
    }

    /**
     * NAVER购物搜索信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class NaverShoppingSearchInfo {
        /**
         * 目录 ID 取值来自目录查询API
         * 카탈로그 ID
         */
        private Long modelId;
        /**
         * 目录名称 取值来自目录查询API
         * 카탈로그명
         */
        private String modelName;
        /**
         * 制造商名称
         * 제조사명
         */
        private String manufacturerName;
        /**
         * 品牌 ID 取值来自获取产品品牌列表API
         * 브랜드 ID
         */
        private Long brandId;
        /**
         * 品牌名 取值来自获取产品品牌列表API
         * 브랜드명
         */
        private String brandName;
        /**
         * 添加目录匹配与否
         * <p>目录匹配与否为True的商品是通过内部验收完成目录匹配的商品。 完成配对的产品型号Id（目录ID）、型号Name（目录名）不能修改。</p>
         * 카탈로그 매칭 여부 추가
         * 카탈로그 매칭 여부가 true인 상품은 내부 검수를 통해 카탈로그가 매칭 완료된 상품입니다. 매칭 완료된 상품의 modelId(카탈로그 ID), modelName(카탈로그명)은 수정할 수 없습니다.
         */
        private Boolean catalogMatchingYn;
    }

    /**
     * 售后服务信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class AfterServiceInfo {
        /**
         * 售后服务电话号码
         * A/S 전화번호
         */
        @NotEmpty(message = "售后服务电话号码不能为空")
        private String afterServiceTelephoneNumber;
        /**
         * 售后服务通知
         * A/S 안내
         */
        @NotEmpty(message = "售后服务通知不能为空")
        private String afterServiceGuideContent;
    }

    /**
     * 购买数量设定信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class PurchaseQuantityInfo {
        /**
         * 最低购买数量
         * 최소 구매 수량
         */
        @Min(value = 0, message = "最低购买数量不能小于0")
        @Max(value = 10000, message = "最低购买数量不能大于10000")
        private Integer minPurchaseQuantity;
        /**
         * 1人最大购买数量
         * 1인 최대 구매 수량
         */
        @Min(value = 0, message = "1人最大购买数量不能小于0")
        @Max(value = 99999999, message = "1人最大购买数量不能大于99999999")
        private Integer maxPurchaseQuantityPerId;
        /**
         * 1次最大购买数量
         * 1회 최대 구매 수량
         */
        @Min(value = 0, message = "1次最大购买数量不能小于0")
        @Max(value = 10000, message = "1次最大购买数量不能大于10000")
        private Integer maxPurchaseQuantityPerOrder;
    }

    /**
     * 原产地信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class OriginAreaInfo {
        /**
         * 原产地详细地区代码 取值来自条件查询原产国代码列表API
         * 00(国产), 01(原产), 02(进口), 03(其他-详细说明中标明), 04(其他-直接输入), 05(不是原产地标记义务对象)。
         * 원산지 상세 지역 코드
         * 00(국산), 01(원양산), 02(수입산), 03(기타-상세 설명에 표시), 04(기타-직접 입력), 05(원산지 표기 의무 대상 아님)
         */
        @NotEmpty(message = "原产地代码不能为空")
        private String originAreaCode;
        /**
         * 进口公司名称
         * <p>进口产品必须</p>
         * 수입사명
         * 수입산인 경우 필수
         */
        private String importer;
        /**
         * 原产地标记内容
         * <p>originAreaCode 为"其他:直接输入"时必需</p>
         * 원산지 표시 내용
         * originAreaCode가 '기타: 직접 입력'인 경우 필수
         */
        private String content;
        /**
         * 多个原产地与否
         * <p>原产地是否一起注册其他商品。输入时，用false。</p>
         * 복수 원산지 여부
         * 원산지가 다른 상품을 같이 등록하는지 여부. 미입력 시 false로 저장됩니다.
         */
        private Boolean plural;
    }

    /**
     * 卖方代码信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class SellerCodeInfo {
        /**
         * 卖方管理代码
         * 판매자 관리 코드
         */
        private String sellerManagementCode;
        /**
         * 卖家条形码
         * 판매자 바코드
         */
        private String sellerBarcode;
        /**
         * 卖方内部代码 1
         * <p>卖家内部使用的代码</p>
         * 판매자 내부 코드 1
         * 판매자가 내부에서 사용하는 코드
         */
        private String sellerCustomCode1;
        /**
         * 卖方内部代码 2
         * <p>卖家内部使用的代码</p>
         * 판매자 내부 코드 2
         * 판매자가 내부에서 사용하는 코드
         */
        private String sellerCustomCode2;
    }

    /**
     * 选项信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class OptionInfo {
        /**
         * 单独选项排序
         * <p>未输入或非许可类型输入时,以默认值即注册顺序(CREATE)保存。 只能输入CREATE、ABC。</p>
         * 단독형 옵션 정렬 순서
         * 미입력 혹은 비허용 타입 입력 시 기본값인 등록순(CREATE)으로 저장됩니다. CREATE, ABC만 입력 가능합니다.
         * <p>
         * CREATE(등록순), ABC(가나다순)
         */
        private SimpleOptionSortType simpleOptionSortType;
        /**
         * 单独型期权
         * <p>最多可以注册3个。</p>
         * <p>标准选项、单独选项、组合选项、直接录入选项中至少应填写一个。</p>
         * <p>标准型选项、单独型选项和组合型选项不能同时使用。</p>
         * 단독형 옵션
         * 최대 3개까지 등록할 수 있습니다.
         * <p>
         * 표준형 옵션, 단독형 옵션, 조합형 옵션, 직접 입력형 옵션 중 최소 한 개는 입력해야 합니다.
         * 표준형 옵션, 단독형 옵션과 조합형 옵션은 함께 사용할 수 없습니다.
         */
        private List<OptionSimple> optionSimple;
        /**
         * 直接输入式选项
         * <p>最多可以注册5个。</p>
         * <p>标准选项、单独选项、组合选项、直接录入选项中至少应填写一个。</p>
         * 직접 입력형 옵션
         * 최대 5개까지 등록할 수 있습니다.
         * <p>
         * 표준형 옵션, 단독형 옵션, 조합형 옵션, 직접 입력형 옵션 중 최소 한 개는 입력해야 합니다.
         */
        private List<OptionSimple> optionCustom;
        /**
         * 组合式选项排序
         * <p>未输入时按默认值即注册顺序(CREATE)保存。</p>
         * <p>对于租赁商品，只能设置CREATE（按注册顺序）、ABC（按字母顺序）。</p>
         * 조합형 옵션 정렬 순서
         * 미입력 시 기본값인 등록순(CREATE)으로 저장됩니다.
         * <p>
         * 렌탈 상품의 경우 CREATE(등록순), ABC(가나다순)만 설정 가능합니다.
         */
        private SimpleOptionSortType optionCombinationSortType;
        /**
         * 组合型选项名
         * <p>组合选项名称列表</p>
         * 조합형 옵션명
         * 조합형 옵션명 목록
         */
        private OptionCombinationGroupNames optionCombinationGroupNames;
        /**
         * 组合式期权
         * <p>最多可登记的选项数量为组合型3个、点位型4个。</p>
         * <p>对于赶集商品，必须登记分店式期权。</p>
         * <p>标准选项、单独选项、组合选项、直接录入选项中至少应填写一个。</p>
         * <p>标准型选项、单独型选项、组合型选项不能同时使用。</p>
         * 조합형 옵션
         * 최대 등록 가능한 옵션 개수는 조합형은 3개, 지점형은 4개입니다.
         * <p>
         * 장보기 상품의 경우 지점형 옵션은 반드시 등록해야 합니다.
         * 표준형 옵션, 단독형 옵션, 조합형 옵션, 직접 입력형 옵션 중 최소 한 개는 입력해야 합니다.
         * 표준형 옵션, 단독형 옵션, 조합형 옵션은 함께 사용할 수 없습니다.
         */
        private List<OptionCombination> optionCombinations;
        /**
         * 标准选项组
         * <p>一组标准选项需要对颜色、尺寸进行注册。</p>
         * 표준형 옵션 그룹
         * 표준형 옵션 그룹은 색상, 사이즈를 등록해야 합니다.
         */
        private List<StandardOptionGroup> standardOptionGroups;
        /**
         * 标准选项
         * <p>标准选项、单独选项、组合选项、直接录入选项中至少应填写一个。</p>
         * <p>标准型选项、单独型选项、组合型选项不能同时使用。</p>
         * 표준형 옵션
         * 표준형 옵션, 단독형 옵션, 조합형 옵션, 직접 입력형 옵션 중 최소 한 개는 입력해야 합니다.
         * <p>
         * 표준형 옵션, 단독형 옵션, 조합형 옵션은 함께 사용할 수 없습니다.
         */
        private List<OptionStandard> optionStandards;
        /**
         * 选项库存数量管理使用与否
         * <p>未输入"是否使用期权库存数量管理"或指定false时，数量设置为9999。</p>
         * 옵션 재고 수량 관리 사용 여부
         * '옵션 재고 수량 관리 사용 여부'를 입력하지 않거나 false로 지정하면 수량이 9,999로 설정됩니다.
         */
        private Boolean useStockManagement;
        /**
         * 各选项配送属性选项值列表
         * <p>如果每个选项都属于交货属性，则至少填写一个。 只能输入第一个选项名对应的选项值。 未输入时维持现有值。</p>
         * 옵션별 배송 속성 옵션값 목록
         * 옵션별 배송 속성인 경우 최소 한 개는 입력합니다. 첫 번째 옵션명에 해당하는 옵션값만 입력 가능합니다. 미입력 시 기존값이 유지됩니다.
         */
        private List<String> optionDeliveryAttributes;
    }

    /**
     * 附加商品
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class SupplementProductInfo {
        /**
         * 追加商品排序分类代码
         * <p>未输入时按默认值即注册顺序(CREATE)保存。</p>
         * 추가 상품 정렬 구분 코드
         * 미입력 시 기본값인 등록순(CREATE)으로 저장됩니다.
         */
        private SimpleOptionSortType sortType;
        /**
         * 附加商品
         * 추가 상품
         */
        private List<SupplementProduct> supplementProducts;
    }

    /**
     * 采购评估信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class PurchaseReviewInfo {
        /**
         * 评论曝光与否
         * 采购评价曝光设置仅限类别（食品）有效，其他设置为True。 未输入时保存为True。
         * 리뷰 노출 여부
         * 구매평 노출 설정 가능 카테고리일 경우(식품)에만 유효하며 그 외에는 true로 설정됩니다. 미입력 시 true로 저장됩니다.
         */
        private Boolean purchaseReviewExposure;
        /**
         * 评论未曝光事由
         * 如果是否显示评论为True，则保存为空值。 评论是否曝光为false时，需填写未曝光理由。
         * 리뷰 미노출 사유
         * 리뷰 노출 여부가 true일 경우 빈 값으로 저장됩니다. 리뷰 노출 여부가 false일 경우 리뷰 미노출 사유를 입력해야 합니다.
         */
        private String reviewUnExposeReason;
    }

    /**
     * 关于 ISBN
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class IsbnInfo {
        /**
         * ISBN 13位 ^[\d*]{13}$
         * <p>'-' 无，请输入13位有效数字。</p>
         * <p>例外类别中属于图书_一般、图书_海外、图书_二手、图书_E书、图书_有声读物时,必须具备。</p>
         * <p>例外类别中属于图书_杂志、图书_定价制free的情况不是必需的。</p>
         * <p>如果是独立出版物，则不是必需的。</p>
         * <p>检查 ISBN 值的有效性 。</p>
         * ISBN 13자리  ^[\d*]{13}$
         * '-' 없이 13자리 유효한 숫자를 입력합니다.
         * <p>
         * 예외 카테고리 중 도서_일반, 도서_해외, 도서_중고, 도서_E북, 도서_오디오북에 해당하는 경우 필수.
         * 예외 카테고리 중 도서_잡지, 도서_정가제free에 해당하는 경우 필수 아님.
         * 독립출판물인 경우 필수 아님.
         * 라이브러리를 통해 ISBN 값의 유효성 체크.
         */
        private String isbn13;
        /**
         * issn 8位 ^[\d*]{7}[\d|X]{1}$
         * <p>例外类别中属于图书_杂志的，请输入。 '-' 无，请输入8位有效数字。</p>
         * ISSN 8자리 ^[\d*]{7}[\d|X]{1}$
         * 예외 카테고리 중 도서_잡지에 해당하는 경우 입력합니다. '-' 없이 8자리 유효한 숫자를 입력합니다.
         */
        private String issn;
        /**
         * 独立出版物与否
         * <p>例外类别中属于图书_一般、图书_海外、图书_二手、图书_定价制free、图书_E书、图书_有声读物时,可以输入。</p>
         * 독립출판물 여부
         * 예외 카테고리 중 도서_일반, 도서_해외, 도서_중고, 도서_정가제free, 도서_E북, 도서_오디오북에 해당하는 경우 입력할 수 있습니다.
         */
        private Boolean independentPublicationYn;
    }

    /**
     * 图书信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class BookInfo {
        /**
         * 出版日期
         * 'YYYY-MM-DD' 格式
         * 출간일
         * 'YYYY-MM-DD' 형식
         */
        @NotEmpty(message = "出版日期不能为空")
        private String publishDay;
        /**
         * 出版社
         * 출판사
         */
        @NotNull(message = "出版社不能为空")
        private SimpleMap publisher;
        /**
         * 作者名
         * 글작가명
         */
        @NotEmpty(message = "作者名不能为空")
        private List<SimpleMap> authors;
        /**
         * 画作作者名
         * 그림작가명
         */
        private List<SimpleMap> illustrators;
        /**
         * 翻译者姓名
         * 번역자명
         */
        private List<SimpleMap> translators;
    }

    /**
     * 简单map-作为图书信息的内部对象
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class SimpleMap {
        /**
         * 代码
         * <p>可在销售者中心查询代码。无法确认代码时不发送。</p>
         * 코드
         * 판매자센터에서 코드 조회 가능. 코드를 확인할 수 없으면 전송하지 않습니다.
         */
        private String code;
        /**
         * 文本
         * <p>作者名，出版社必须输入必填值。 如果代码不是NULL，则应以映射到该代码的名称进行传输。 没有代码，只发送名字，没有代码。</p>
         * 텍스트
         * 글작가명, 출판사는 필수값으로 입력해야 합니다. 코드가 NULL이 아닌 경우 해당 코드에 매핑된 이름으로 전송해야 합니다. 코드가 없으면, 코드 없이 이름만 전송합니다.
         */
        private String text;
    }

    /**
     * 认证信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class ProductCertificationInfo {
        /**
         * 认证类型 ID
         * 인증 유형 ID
         */
        private Long certificationInfoId;
        /**
         * 认证信息类型代码
         * <p>认证信息类型字段可设置的代码。 未输入时保存为ETC。</p>
         * 인증 정보 종류 코드
         * 인증 정보 종류 필드에 설정 가능한 코드입니다. 미입력 시 ETC로 저장됩니다.
         */
        private CertificationKindType certificationKindType;
        /**
         * 认证机构名称
         * <p>儿童产品/生活用品/电器用品供应商适合性类型时非必需</p>
         * 인증 기관명
         * 어린이제품/생활용품/전기용품 공급자적합성 유형인 경우 비필수
         */
//        @NotEmpty(message = "认证机构名称不能为空")
        private String name;
        /**
         * 验证码
         * <p>儿童产品/生活用品/电器用品供应商适合性类型时非必需</p>
         * 인증번호
         * 어린이제품/생활용품/전기용품 공급자적합성 유형인 경우 비필수
         */
//        @NotEmpty(message = "验证码不能为空")
        private String certificationNumber;
        /**
         * 是否使用认证标志
         * <p>未输入时保存为false。</p>
         * 인증마크 사용 여부
         * 미입력 시 false로 저장됩니다.
         */
        private Boolean certificationMark;
        /**
         * 授权商号名
         * <p>认证类型为广播通信器材合格认证/合格注册/临时认证、儿童产品安全认证/安全确认时必需使用</p>
         * 인증 상호명
         * 인증 유형이 방송통신기자재 적합인증/적합등록/잠정인증, 어린이제품 안전인증/안전확인인 경우 필수
         */
        private String companyName;
        /**
         * 认证日期
         * <p>'yyyy-MM-dd' 输入格式</p>
         * <date> (인증일자)
         * 'yyyy-MM-dd' 형식 입력
         */
        private String certificationDate;
    }

    /**
     * 是否排除认证对象的信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class CertificationTargetExcludeContent {
        /**
         * 儿童产品认证对象除外与否
         * <p>儿童产品认证对象类别商品时必需使用。 未输入时保存为false。</p>
         * 어린이제품 인증 대상 제외 여부
         * 어린이제품 인증 대상 카테고리 상품인 경우 필수. 미입력 시 false로 저장됩니다.
         */
        private Boolean childCertifiedProductExclusionYn;
        /**
         * KC 豁免目标类型代码
         * <p>遵守安全标准、代购、并行进口时需输入</p>
         * KC 면제 대상 타입 코드
         * 안전기준준수, 구매대행, 병행수입인 경우 필수 입력
         */
        private KcExemptionType kcExemptionType;
        /**
         * KC商品认证对象除外类型
         * <p>"KC认证对象"类别商品时必需,未输入时保存为FALSE。</p>
         * KC 상품 인증 대상 제외 타입
         * 'KC 인증 대상' 카테고리 상품인 경우 필수, 미입력 시 FALSE로 저장됩니다.
         */
        private KcCertifiedProductExclusionYn kcCertifiedProductExclusionYn;
        /**
         * 是否排除在环保认证对象之外
         * <p>如果是"环保认证对象"类别商品,必须,未输入时保存为false。</p>
         * 친환경 인증 대상 제외 여부
         * '친환경 인증 대상' 카테고리 상품인 경우 필수, 미입력 시 false로 저장됩니다.
         */
        private Boolean greenCertifiedProductExclusionYn;
    }

    /**
     * E优惠券
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class Ecoupon {
        /**
         * E优惠券有效期分类代码
         * E쿠폰 유효기간 구분 코드
         */
        private PeriodType periodType;
        /**
         * E优惠券有效期起始日
         * <p>E优惠券有效期分类类型(PeriodType)为"特定期间"时必需。输入"yyyy-MM-dd"格式。</p>
         * date> (E쿠폰 유효기간 시작일)
         * E쿠폰 유효기간 구분 타입(PeriodType)이 '특정 기간'인 경우 필수. 'yyyy-MM-dd' 형식 입력.
         */
        private String validStartDate;
        /**
         * E优惠券有效期截止日
         * <p>E优惠券有效期分类类型(PeriodType)为"特定期间"时必需。输入"yyyy-MM-dd"格式。</p>
         * <date> (E쿠폰 유효기간 종료일)
         * E쿠폰 유효기간 구분 타입(PeriodType)이 '특정 기간'인 경우 필수. 'yyyy-MM-dd' 형식 입력.
         */
        private String validEndDate;
        /**
         * E优惠券有效期内容（购买日起00日）
         * <p>E优惠券有效期分类类型（PeriodType）为"自动期限"时必需使用</p>
         * (E쿠폰 유효기간 내용(구매일로부터 00일))
         * E쿠폰 유효기간 구분 타입(PeriodType)이 '자동 기간'인 경우 필수
         */
        private Integer periodDays;
        /**
         * E优惠券发行处内容
         * E쿠폰 발행처 내용
         */
        @NotEmpty(message = "E优惠券发行处内容不能为空")
        private String publicInformationContents;
        /**
         * E优惠券联系方式内容
         * E쿠폰 연락처 내용
         */
        @NotEmpty(message = "E优惠券联系方式内容不能为空")
        private String contactInformationContents;
        /**
         * E优惠券使用场所分类代码
         * E쿠폰 사용 장소 구분 코드
         */
        @NotEmpty(message = "E优惠券使用场所分类代码不能为空")
        private UsePlaceType usePlaceType;
        /**
         * 使用地点内容
         * <p>ECouponUsePlace Type.ADDRESS时输入地址簿编号</p>
         * 사용 장소 내용
         * ECouponUsePlaceType.ADDRESS인 경우 주소록 일련번호를 입력
         */
//        @NotEmpty(message = "使用地点内容不能为空")
        private String usePlaceContents;
        /**
         * 购物车不可购买与否
         * <p>E优惠券购物车限制。 未输入时设定为false。</p>
         * <p>true:只能立即购买，false:可以立即购买，可以购买购物车</p>
         * 장바구니 구매 불가 여부)
         * E쿠폰 장바구니 제한. 미입력 시 false로 설정됩니다.
         * <p>
         * true: 즉시 구매만 가능, false: 즉시 구매, 장바구니 구매 가능
         */
        private Boolean restrictCart;
        /**
         * 网站名称
         * 사이트명
         */
        private String siteName;
    }

    /**
     * 商品属性列表
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class ProductAttribute {
        /**
         * 属性 ID
         * 속성 ID
         */
        private Integer attributeSeq;
        /**
         * 属性值 ID
         * 속성값 ID
         */
        @NotNull(message = "属性值 ID不能为空")
        private Integer attributeValueSeq;
        /**
         * 属性实际值
         * <p>范围型时输入。 当属性不能像范围类型那样指定特定值时使用。</p>
         * 속성 실제 값
         * 범위형인 경우 입력합니다. 범위형처럼 속성의 특정 값을 지정할 수 없을 때 사용합니다.
         */
        private String attributeRealValue;
        /**
         * 属性实际值单位代码
         * <p>范围型时输入。</p>
         * 속성 실제 값 단위 코드
         * 범위형인 경우 입력합니다.
         */
        private String attributeRealValueUnitCode;
    }

    /**
     * SEO
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class SeoInfo {
        /**
         * 页面标题 <= 100 characters
         * 페이지 타이틀
         */
        @Size(max = 100, message = "页面标题 <= 100 characters")
        private String pageTitle;
        /**
         * 元信息 <= 160 characters
         * 메타 정보
         */
        @Size(max = 160, message = "元信息 <= 160 characters")
        private String metaDescription;
        /**
         * 卖方输入标签 <= 4000 characters
         * 판매자 입력 태그
         */
        private List<SimpleMap> sellerTags;
    }

    /**
     * 商品尺寸 尺寸信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class ProductSize {
        /**
         * 尺寸类型编号 取值来自获取所有产品尺寸和类型集合API
         * 사이즈 타입 번호
         */
        private Long sizeTypeNo;
        /**
         * 商品详细尺寸属性
         * 상품 상세 사이즈 속성
         */
        @NotEmpty(message = "商品详细尺寸属性不能为空")
        private List<SizeAttribute> sizeAttributes;
        /**
         * 时装模特信息
         * 패션모델 정보
         */
        private List<Model> models;
    }

    /**
     * 商品详细尺寸属性
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class SizeAttribute {
        /**
         * 商品详细尺寸项目名称
         * 상품 상세 사이즈 항목 이름
         */
        @NotEmpty(message = "商品详细尺寸项目名称不能为空")
        private String name;
        /**
         * 商品尺码列表
         * 상품 사이즈 값 목록
         */
        @NotEmpty(message = "商品尺码列表不能为空")
        private List<SizeValue> sizeValues;
    }

    /**
     * 商品尺码
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class SizeValue {
        /**
         * 尺寸值类型编号 取值来自获取所有产品尺寸和类型集合API
         * 사이즈 값 타입 번호
         */
        @NotNull(message = "尺寸值类型编号不能为空")
        private Long sizeValueTypeNo;
        /**
         * 尺寸值
         * 사이즈 값
         */
        @NotNull(message = "尺寸值不能为空")
        private BigDecimal value;
    }

    /**
     * 时装模特信息
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class Model {
        /**
         * 时装模特编号
         * 패션모델 번호
         */
        @NotNull(message = " 时装模特编号不能为空")
        private Long modelId;
        /**
         * 时装模特名
         * 패션모델명
         */
        private String name;
        /**
         * 时装模特key
         * 패션모델 키
         */
        private Integer height;
        /**
         * 时装模特体重
         * 패션모델 몸무게
         */
        private Integer weight;
        /**
         * 时装模特上衣尺码
         * 패션모델 상의 사이즈
         */
        private String top;
        /**
         * 时装模特下衣尺寸
         * 패션모델 하의 사이즈
         */
        private String bottom;
        /**
         * 时装模特鞋码
         * 패션모델 신발 사이즈
         */
        private String shoe;
    }

    /**
     * 卖方基本折扣政策
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class ImmediateDiscountPolicy {
        /**
         * 折扣优惠
         * 할인 혜택
         */
        private DiscountMethod discountMethod;
        /**
         * 手机打折优惠 (废弃)
         * 모바일 할인 혜택（Deprecated）
         */
        private DiscountMethod mobileDiscountMethod;
    }

    /**
     * 折扣优惠
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class DiscountMethod {
        /**
         * 折扣值
         * <p>根据折扣单位输入值。</p>
         * <p>固定费率10%的话10，固定费率100韩元的话100</p>
         * 할인 값 [ 1 .. 10000000 ]
         * 할인 단위에 따른 값을 입력합니다.
         * 예: 정율 10%이면 10, 정액 100원이면 100
         */
        @NotNull(message = "折扣值不能为空")
        private BigDecimal value;
        /**
         * 贴现单位
         * <p>折价单位类型。 只能输入PERCENT、WON。</p>
         * 할인 단위
         * 할인 단위 타입. PERCENT, WON만 입력 가능합니다.
         */
        @NotNull(message = "贴现单位不能为空")
        private UnitType unitType;
        /**
         * 折扣起始日
         * <p>每个时间只能设置为00、10、20、30、40、50分钟。 以"yyy-MM-dd'T'HH:mm[:ss][.SSS]XXX"格式输入。</p>
         * <date-time> (할인 시작일)
         * 매 시각 00, 10, 20, 30, 40, 50분으로만 설정 가능합니다. 'yyyy-MM-dd'T'HH:mm[:ss][.SSS]XXX' 형식으로 입력합니다.
         */
        private String startDate;
        /**
         * 折扣结束日
         * <p>每小时只能设置09、19、29、39、49、59分钟。 以"yyy-MM-dd'T'HH:mm[:ss][.SSS]XXX"格式输入。</p>
         * <date-time> (할인 종료일)
         * 매 시각 09, 19, 29, 39, 49, 59분으로만 설정 가능합니다. 'yyyy-MM-dd'T'HH:mm[:ss][.SSS]XXX' 형식으로 입력합니다.
         */
        private String endDate;
    }

    /**
     * 商品购买积分政策
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class PurchasePointPolicy {
        /**
         * 商品购买积分值
         * <p>请输入以积分为单位的值。</p>
         * <p>固定费率10%的话10，固定费率100韩元的话100</p>
         * 상품 구매 포인트 값
         * 포인트 단위에 따른 값을 입력합니다.
         * 예: 정율 10%이면 10, 정액 100원이면 100
         */
        @NotNull(message = "商品购买积分值不能为空")
        private BigDecimal value;
        /**
         * 商品购买积分单位
         * <p>商品购买积分单位类型。 只能输入PERCENT、WON。</p>
         * 상품 구매 포인트 단위
         * 상품 구매 포인트 단위 타입. PERCENT, WON만 입력 가능합니다.
         */
        @NotNull(message = "商品购买积分单位不能为空")
        private UnitType unitType;
        /**
         * 累积起始日 'yyyy-MM-dd'输入格式
         * <date> 적립 시작일
         * 'yyyy-MM-dd' 형식 입력
         */
        private String startDate;
        /**
         * 累计结束日
         * <p>输入起始日期时必需。 输入" yyy-MM-dd" 格式 。</p>
         * <date> (적립 종료일)
         * 시작일을 입력한 경우 필수. 'yyyy-MM-dd' 형식 입력.
         */
        private String endDate;
    }

    /**
     * 购买评价积分政策
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class ReviewPointPolicy {
        /**
         * 文字评论要点
         * <p>发表文字评论时累积的Naver Pay积分</p>
         * 텍스트 리뷰 포인트
         * 텍스트 리뷰 작성 시 적립되는 네이버페이 포인트
         */
        private Integer textReviewPoint;
        /**
         * 照片/视频点评要点
         * <p>发表照片/视频评论时累积的Naver Pay积分</p>
         * 포토/동영상 리뷰 포인트
         * 포토/동영상 리뷰 작성 시 적립되는 네이버페이 포인트
         */
        private Integer photoVideoReviewPoint;
        /**
         * 一个月使用文本评论要点
         * <p>一个月使用文本评论时累积的Naver Pay积分</p>
         * 한 달 사용 텍스트 리뷰 포인트
         * 한 달 사용 텍스트 리뷰 작성 시 적립되는 네이버페이 포인트
         */
        private Integer afterUseTextReviewPoint;
        /**
         * 一个月使用照片/视频评价要点
         * <p>一个月使用照片/视频评论时累积的Naver Pay积分</p>
         * 한 달 사용 포토/동영상 리뷰 포인트
         * 한 달 사용 포토/동영상 리뷰 작성 시 적립되는 네이버페이 포인트
         */
        private Integer afterUsePhotoVideoReviewPoint;
        /**
         * 同意接受通知/消息通知（talk talk朋友）会员评论追加积分
         * <p>同意接受通知/TalkTalk好友会员发表商品评价、一个月使用评价时追加积累的Naver Pay积分</p>
         * <p>不区分文本评论或照片/视频评论，只提供1次</p>
         * 알림받기 동의/소식알림(톡톡친구) 회원 리뷰 추가 적립 포인트
         * 알림받기 동의/톡톡친구 회원이 상품 리뷰, 한 달 사용 리뷰 작성 시 추가 적립되는 네이버페이 포인트
         * <p>
         * 텍스트 리뷰나 포토/동영상 리뷰 구분 없이 1회만 지급
         */
        private Integer storeMemberReviewPoint;
        /**
         * 累积起始日
         * <p>Naver Pay积分有效期开始日期。 输入" yyy-MM-dd" 类型 。</p>
         * 적립 시작일
         * 네이버페이 포인트 유효기간 시작일. 'yyyy-MM-dd' 형식 입력.
         */
        private String startDate;
        /**
         * 累计结束日
         * <p>Naver Pay积分有效期结束日。 输入起始日期时必需。 输入" yyy-MM-dd" 格式 。</p>
         * 적립 종료일
         * 네이버페이 포인트 유효기간 종료일. 시작일을 입력한 경우 필수. 'yyyy-MM-dd' 형식 입력.
         */
        private String endDate;
    }

    /**
     * 无息分期付款政策
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class FreeInterestPolicy {
        /**
         * 无息分期付款月数
         * 무이자 할부 개월 수
         */
        @NotNull(message = "无息分期付款月数不能为空")
        private Integer value;
        /**
         * 无息分期付款起始日 输入" yyy-MM-dd" 类型
         * <date> (무이자 할부 시작일)
         * 'yyyy-MM-dd' 형식 입력
         */
        private String startDate;
        /**
         * 无息分期付款终止日 输入起始日期时必需。 输入" yyy-MM-dd" 格式 。
         * <date> (무이자 할부 종료일)
         * 시작일을 입력한 경우 필수. 'yyyy-MM-dd' 형식 입력.
         */
        private String endDate;
    }

    /**
     * 赠品政策
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class GiftPolicy {
        /**
         * 赠品 赠品内容
         * 사은품
         * 사은품 내용
         */
        private String presentContent;
    }

    /**
     * 复购折扣政策
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class MultiPurchaseDiscountPolicy {
        /**
         * 多次购买打折优惠
         * 복수 구매 할인 혜택
         */
        private DiscountMethod discountMethod;
        /**
         * 订货金额（数量）值
         * 주문 금액(수량) 값
         */
        @NotNull(message = "订货金额（数量）值不能为空")
        private BigDecimal orderValue;
        /**
         * 订货金额（数量）单位 只能输入COUNT、WON。
         * 주문 금액(수량) 단위
         * COUNT, WON만 입력 가능합니다.
         */
        @NotNull(message = "订货金额（数量）单位不能为空")
        private UnitType orderValueUnitType;
    }

    /**
     * 预约折扣政策
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class ReservedDiscountPolicy {
        /**
         * 预约打折优惠
         * 예약 할인 혜택
         */
        private DiscountMethod discountMethod;
    }

    /**
     * 单独型期权
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class OptionSimple {
        /**
         * 选项序列号
         * <p>输入选项ID时修改现有选项</p>
         * 옵션 일련번호
         * 옵션 ID 입력 시 기존 옵션 수정
         */
        private Long id;
        /**
         * 期权名称
         * 옵션명
         */
        @NotEmpty(message = "期权名称不能为空")
        private String groupName;
        /**
         * 期权价格
         * <p>如果是"单独选项"，请输入。 "直接输入型选项"时将被忽略</p>
         * 옵션값
         * "단독형 옵션"인 경우 입력합니다. "직접 입력형 옵션"인 경우 무시됩니다
         */
        private String name;
        /**
         * 是否启用
         * <p>未输入时使用与否设定为true。</p>
         * 사용 여부
         * Default: true
         * 미입력 시 사용 여부는 true로 설정됩니다.
         */
        private Boolean usable;
    }

    /**
     * 组合型选项名
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class OptionCombinationGroupNames {
        /**
         * 组合型选项名 1
         * 조합형 옵션명 1
         */
        @NotEmpty(message = "组合型选项名1不能为空")
        private String optionGroupName1;
        /**
         * 组合型选项名 2
         * 조합형 옵션명 2
         */
        private String optionGroupName2;
        /**
         * 组合型选项名 3
         * 조합형 옵션명 3
         */
        private String optionGroupName3;
        /**
         * 组合型选项名 4
         * <p>仅以"地点型选项"为对象。 "组合型选项"时将被忽略。</p>
         * 조합형 옵션명 4
         * "지점형 옵션"인 경우만 대상. "조합형 옵션"인 경우 무시됩니다.
         */
        private String optionGroupName4;

    }

    /**
     * 组合式期权
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class OptionCombination {
        /**
         * 组合式选项ID
         * <p>输入选项ID时修改现有选项</p>
         * (조합형 옵션 ID)
         * 옵션 ID 입력 시 기존 옵션 수정
         */
        private Long id;
        /**
         * 组合型选项值1
         * <p>combination OptionNames 的选项名1对应的选项值 。 采购账户请求，即分支机构选项（BRANCH），在该字段中填写分支机构ID，而不是选项名称。</p>
         * (조합형 옵션값 1)
         * combinationOptionNames의 옵션명 1에 해당하는 옵션값. 장보기 계정 요청, 즉 지점 옵션(BRANCH)인 경우, 해당 필드에 옵션명이 아닌 지점 ID를 입력합니다.
         */
        @NotEmpty(message = "组合式期权1不能为空")
        private String optionName1;
        /**
         * 组合型选项值2
         * <p>combination OptionNames 的选项名2对应的选项值</p>
         * (조합형 옵션값 2)
         * combinationOptionNames의 옵션명 2에 해당하는 옵션값
         */
        private String optionName2;
        /**
         * 组合型选项值3
         * <p>combination OptionNames 的选项名3对应的选项值</p>
         * (조합형 옵션값 3)
         * combinationOptionNames의 옵션명 3에 해당하는 옵션값
         */
        private String optionName3;
        /**
         * 组合式选项值4
         * <p>combination OptionNames 的选项名4对应的选项值</p>
         * (조합형 옵션값 4)
         * combinationOptionNames의 옵션명 4에 해당하는 옵션값. '지점형 옵션'인 경우만 대상. "조합형 옵션"인 경우 무시됩니다.
         */
        private String optionName4;
        /**
         * 库存数量 <= 99999999
         * (재고 수량) <= 99999999
         * 미입력 시 0개
         */
        @Min(value = 0, message = "库存数量不能小于0")
        @Max(value = 99999999, message = "库存数量不能大于99999999")
        private Integer stockQuantity;
        /**
         * 期权价格 <= 999999990
         * (옵션가) <= 999999990
         * 미입력 시 0원
         */
        @Min(value = 0, message = "期权价格不能小于0")
        @Max(value = 999999990, message = "期权价格不能大于999999990")
        private Integer price;
        /**
         * 销售者管理代码
         * (판매자 관리 코드)
         */
        private String sellerManagerCode;
        /**
         * 启用与否 未输入时使用与否设定为true。
         * (사용 여부)
         * Default: true
         * 미입력 시 사용 여부는 true로 설정됩니다.
         */
        private Boolean usable;
    }

    /**
     * 标准选项组
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class StandardOptionGroup {
        /**
         * 标准选项组类型
         * 표준형 옵션 그룹 타입
         */
        @NotEmpty(message = "标准选项组类型不能为空")
        private String groupName;
        /**
         * 标准选项属性
         * 표준형 옵션 속성
         */
        private List<StandardOptionAttribute> standardOptionAttributes;
    }

    /**
     * 标准选项属性
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class StandardOptionAttribute {
        /**
         * 属性 ID 取值来自根据categoryId搜索标准选项
         * 속성 ID
         */
        @NotNull(message = "属性ID不能为空")
        private Long attributeId;
        /**
         * 属性值 ID 取值来自根据categoryId搜索标准选项
         * 속성값 ID
         */
        @NotNull(message = "属性值ID不能为空")
        private Long attributeValueId;
        /**
         * 属性值名称 取值来自根据categoryId搜索标准选项
         * 속성값 이름
         */
        @NotNull(message = "属性值名称不能为空")
        private String attributeValueName;
        /**
         * 在标准选项中使用的图像 URL 列表
         * <p>图像URL必须上传图像到商品图像多件注册API，并输入返回的URL值。</p>
         * 표준형 옵션에서 사용할 이미지 URL 목록)
         * 이미지 URL은 반드시 상품 이미지 다건 등록 API로 이미지를 업로드하고 반환받은 URL 값을 입력해야 합니다.
         */
        private List<String> imageUrls;
    }

    /**
     * 标准选项
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class OptionStandard {
        /**
         * 标准选项 ID
         * <p>输入选项ID时修改现有选项</p>
         * 표준형 옵션 ID
         * 옵션 ID 입력 시 기존 옵션 수정
         */
        private Long id;
        /**
         * 标准选项值 1
         * 표준형 옵션값 1
         */
        @NotEmpty(message = "标准选项1不能为空")
        private String optionName1;
        /**
         * 标准选项值 2
         * 표준형 옵션값 2
         */
        private String optionName2;
        /**
         * (库存数量) <= 99999999
         * <p>仅用于选项库存数量管理设置是否使用。 未输入时保存为0。</p>
         * (재고 수량) <= 99999999
         * 옵션 재고 수량 관리 사용 여부 설정 시에만 활용됩니다. 미입력 시 0으로 저장됩니다.
         */
        @Min(value = 0, message = "库存数量不能小于0")
        @Max(value = 99999999, message = "库存数量不能大于99999999")
        private Integer stockQuantity;
        /**
         * 卖方管理代码
         * 판매자 관리 코드
         */
        private String sellerManagerCode;
        /**
         * 是否启用
         * <p>未输入时使用与否设定为true。</p>
         * 사용 여부
         * Default: true
         * 미입력 시 사용 여부는 true로 설정됩니다.
         */
        private Boolean usable;
    }

    /**
     * 附加商品
     */
    @Getter
    @Setter
    @ToString(callSuper = true)
    public static class SupplementProduct {
        /**
         * 附加商品ID
         * 추가 상품 ID
         */
        private Long id;
        /**
         * 附加商品组名
         * <p>追加商品名</p>
         * 추가 상품 그룹명
         * 추가 상품명
         */
        @NotEmpty(message = "附加商品组名不能为空")
        private String groupName;
        /**
         * 追加商品名
         * <p>额外货款</p>
         *추가 상품명
         * 추가 상품값
         */
        @NotEmpty(message = "追加商品名不能为空")
        private String name;
        /**
         * 追加商品价格<=999999990
         * <p>未输入时输入0韩元。</p>
         *  추가 상품가 <= 999999990
         * 미입력 시 0원으로 입력됩니다.
         */
        @Min(value = 0, message = "追加商品价格不能小于0")
        @Max(value = 999999990, message = "追加商品价格不能大于999999990")
        private Integer price;
        /**
         * 库存数量 <= 99999999
         * <p>未输入时输入0个。</p>
         * 재고 수량 <= 99999999
         * 미입력 시 0개로 입력됩니다.
         */
        @Min(value = 0, message = "库存数量不能小于0")
        @Max(value = 99999999, message = "库存数量不能大于99999999")
        private Integer stockQuantity;
        /**
         * 卖方管理代码
         * 판매자 관리 코드
         */
        private String sellerManagementCode;
        /**
         * 是否启用
         * <p>未输入时输入为true。</p>
         * 사용 여부
         * 미입력 시 true로 입력됩니다.
         */
        private Boolean usable;
    }
}
